<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 封装是指将一些重复的代码封装成一个函数，方便后续调用。
        // 封装一个叫做getJSON的函数，用于获取JSON格式的数据。使用ajax实现。
        const getJSON = (url) =>   // 将function转化为箭头函数（因为被优化为了一行代码）能直接返回一个promise实例，不需要再用return返回
        {
            // 让以下的函数返回一个promise实例，Promise里定义了then方法
            new Promise((resolve,reject)=>{  // resolve是成功的回调函数，reject是失败的回调函数
                // executor 执行器函数，实际是同步执行的，在实例化Promise对象时就会调用。
                // 将耗时的异步任务放在执行器函数中，等异步任务完成后，再调用resolve或reject函数
                const xhr = new XMLHttpRequest();
                xhr.open('GET',url,true);
                xhr.send();
                // 监听状态改变事件
                xhr.onreadystatechange = function () {
                    if (xhr.readyState === 4 && xhr.status === 200) { // 4是请求完成，200是数据请求成功
                        const data = JSON.parse(xhr.responseText);  // data是解析后的JSON格式的数据
                        resolve(data); // 调用成功的回调函数，将数据传递给then方法
                    }}
                xhr.onerror = function () { // 监听错误事件
                    reject('请求失败'); // reject方法是将错误信息传递给catch方法
                }
            }); 
        }
        // promise 是es6提供的异步编程解决方案，优于回调函数
        // promise 就是通过实例化 Promise 对象，然后调用 then 方法，来处理异步操作的结果。
        getJSON('https://api.github.com/users/shunwuyu')
        // promise 
        // .then() 会在promise 实例 resolve 后运行
        .then((data) => {   // .then()方法是一个 Promise 原型（Promise.prototype）上的方法，所以只要返回一个实例化的promise对象，就可以链式调用.then()方法。
            console.log(data);
        })
        .catch((err) => {  // .catch()方法和.then()方法一样，只是处理的是promise实例 reject 后的情况。
            console.log(err);
        })
    </script>
</body>
</html>